#ifndef OGRFILEFORMAT_H_INCLUDED
#define OGRFILEFORMAT_H_INCLUDED

/** include config.h **/
#include "config.h"

#include <iostream>
#include <string>

/** OGR from GDAL Library **/
#include <ogrsf_frmts.h>


#ifdef WINDOWS
    #pragma comment(lib, "gdal_i.lib")
#endif
#ifdef LINUX
#include <unistd.h>
#endif
#include "AbstractDatabase.h"
#include "MemoryFileFormat.h"
#include "AbstractFileFormat.h"

/**
* Basis Klasse für alle Dateiformate, die die OGR Bibliothek verwenden. Von den abgeleiteten Klassen müssen nur noch die entsprechenden Treiber und Konfigurationen gesetzt werden.
**/
class OGRFileFormat : public AbstractFileFormat
{
public:
    /**
    * Konstruktor der die Datenbank und Dateiformat Konfigurationen für die OGR Bibliothek setzt.
    **/
    OGRFileFormat(PFSInfo info);
    /**
    * Destruktor oder OGRFileFormat Klasse.
    **/
    ~OGRFileFormat();

    /**
    * Diese Methode schreibt den Inhalt der mitgeschickt wird in den Arbeitsspeicher. Das Eigentliche Speichern wird von der run() und convert() Methode ausgeführt. Dabei werden diese auf den Inhalt der in den Arbeitsspeicher geschrieben wurde zugegriffen wird.
    **/
    int write(PFSInfo info);

    /**
    * Diese Methode wird aufgerufen, wenn das Dateiformat gelesen wird. Dabei wird in das Info Object der konvertierte Inhalt aus der Datenbank in das jeweilige Format geschrieben.
    **/
    int read(PFSInfo info);
    /**
    * Die Close Methode ist für das Starten des thread zuständig, die die run() Methode ausführt. Dabei ist zu beachten, das nur die erste Datei des Dateiformats die geöffnet wurde die Fähigkeit besitzt diesen Thread zu starten.
    **/
    int close(PFSInfo info);

    /**
    * Registriert eine Datei Operation, da einige Dateiformate aus mehren Dateien bestehen. So das am Ende genau ein Thread für das Laden zuständig ist und erst wenn dieser beendet können die andere Dateien auf die geladenen Dateien zugreifen.
    **/
	int loadDataFromDatabase(PFSInfo info);
    /**
    * Konvertiert Daten aus der Datenbank in das angeforderte Format und andersherum.
    **/
    static int convert(PString dstDriverName, PString srcDriverName, PString dstFile, PString srcFile, PString dstLayerName, PString srcLayerName, char** options, bool isRead);

    /**
    * Die wait Methode wird erst beenden, wenn alle Dateioperationen abgeschlossen sind und wenn eine gewisse Zeit abgelaufen ist.
    **/
	static void wait(PFilesystem filesystem, String &path, String &mainExtension, unsigned int sleeptime);

    /**
    * Diese Methode ist für das Überprüfen der Dateizuständig ob sie geändert wurden. Wenn ja, wird die convert() Methode aufgerufen so das die Änderungen an die Datenbank geschickt werden.
    * Nachdem alles ausgeführt wurde, wird der Cache geleert. Diese Methode wird in einem eingenständigen Thread ausgeführt. Da ungewiss ist aus wieviele Dateien das Dateiformat besteht.
    **/
	static void run(FSInfo info, String dstDriverName, String srcDriverName, String srcFile, String mainExtension);
protected:
	bool firstWrite;
	bool isChanged;
    bool ogrReadMode;
    bool ogrWriteMode;
	bool ogrReadWriteMode;
	bool ogrTruncate;
    MemoryFileFormat* memory;

    String dstDriverName;
    String srcDriverName;

    String dstLayerName;
    String srcLayerName;

    String srcFile; //Database DSN
    String dstFile;

    String mainExtension;
};


#endif // OGRFILEFORMAT_H_INCLUDED
